﻿using SuperFx;
using SuperLottery.Datas.DbModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SuperLottery.Datas
{
	public class LotteryDrawDbService
	{
		public static readonly LotteryDrawDbService Instance = new LotteryDrawDbService();

		private MeiRiCaiEntities NewDB()
		{
			return new MeiRiCaiEntities();
		}

		public List<LatestLotteryDraw> GetLatestLotteryDraws()
		{
			var db = this.NewDB();
			var result = db.LatestLotteryDraw.OrderByDescending(p => p.DrawDate).ToList();
			return result;
		}

		public List<LatestLotteryDraw> GetLatestLotteryDraws(int count, int page)
		{
			var db = this.NewDB();
			var result = db.LatestLotteryDraw.OrderByDescending(p => p.DrawDate)
				.Skip(count * (page - 1)).Take(count)
				.ToList();
			return result;
		}

		public LatestLotteryDraw GetLatestLotteryDraw(string issuer, string game)
		{
			var db = this.NewDB();
			return this.GetLatestLotteryDraw(db, issuer, game);
		}

		internal LatestLotteryDraw GetLatestLotteryDraw(MeiRiCaiEntities db, string issuer, string game)
		{
			var result = db.LatestLotteryDraw.Where(p => p.Issuer == issuer && p.Game == game).SingleOrDefault();
			return result;
		}

		public List<LotteryDraw> GetLotteryDraws(int count, int page)
		{
			var db = this.NewDB();
			var result = db.LotteryDraw.OrderByDescending(p => p.DrawDate)
				.Skip(count * (page - 1)).Take(count)
				.ToList();
			return result;
		}

		public List<LotteryDraw> GetLotteryDraws(string issuer, string game, int count, int page)
		{
			var db = this.NewDB();
			var result = db.LotteryDraw.Where(p => p.Issuer == issuer && p.Game == game)
				.OrderByDescending(p => p.DrawDate)
				.Skip(count * (page - 1)).Take(count)
				.ToList();
			return result;
		}

		public LotteryDraw GetLotteryDraw(long id)
		{
			var db = this.NewDB();
			return this.GetLotteryDraw(db, id);
		}

		public LotteryDraw GetLotteryDraw(MeiRiCaiEntities db, long id)
		{
			return db.LotteryDraw.Where(p => p.Id == id).SingleOrDefault();
		}

		public LotteryDraw GetLotteryDraw(string issuer, string game, string issueNumber)
		{
			var db = this.NewDB();
			return this.GetLotteryDraw(db, issuer, game, issueNumber);
		}

		public LotteryDraw GetLotteryDraw(MeiRiCaiEntities db, string issuer, string game, string issueNumber)
		{
			var result = db.LotteryDraw.Where(p => p.Issuer == issuer && p.Game == game && p.IssueNumber == issueNumber)
				.SingleOrDefault();
			return result;
		}

		public List<WinningDetail> GetWinningDetails(long drawId)
		{
			var db = this.NewDB();
			return this.GetWinningDetails(db, drawId);
		}

		public List<WinningDetail> GetWinningDetails(MeiRiCaiEntities db, long drawId)
		{
			return db.WinningDetail.Where(p => p.DrawId == drawId).ToList();
		}

		public bool Exists(string issuer, string game, string issueNumber)
		{
			var db = this.NewDB();
			var result = db.LotteryDraw.Where(p => p.Issuer == issuer && p.Game == game && p.IssueNumber == issueNumber)
				.Count() > 0;
			return result;
		}

		public LotteryDraw Create(LotteryDraw entity)
		{
			var db = this.NewDB();
			if (this.Exists(entity.Issuer, entity.Game, entity.IssueNumber))
			{
				throw new Exception(String.Format("彩种={0}，期号={1}，已经存在", entity.Issuer + entity.Game, entity.IssueNumber));
			}
			entity.AddTime = DateTime.Now;
			entity.UpdateTime = entity.AddTime;
			db.LotteryDraw.Add(entity);
			db.SaveChanges();

			return entity;
		}

		public LotteryDraw Update(LotteryDraw entity)
		{
			var db = this.NewDB();
			var oldEntity = this.GetLotteryDraw(db, entity.Issuer, entity.Game, entity.IssueNumber);
			if (oldEntity == null)
			{
				oldEntity = this.GetLotteryDraw(db, entity.Id);
				if (oldEntity == null)
				{
					throw new Exception("更新实体的对应的主键不存在");
				}
			}
			else if (oldEntity.Id != entity.Id)
			{
				throw new Exception("由彩种（Issuer，Game）和期号（IssueNumber）组成的业务码已经存在");
			}

			ObjectConverter.SetObjectValue<LotteryDraw>(entity, oldEntity, new string[] { "Id", "AddTime", "UpdateTime" });
			oldEntity.UpdateTime = DateTime.Now;

			db.SaveChanges();
			return oldEntity;
		}

		public LatestLotteryDraw SaveToLatest(LotteryDraw entity)
		{
			var latestLotteryDraw = entity.Convert2<LatestLotteryDraw>();

			var db = this.NewDB();
			LatestLotteryDraw oldEntity = this.GetLatestLotteryDraw(db, entity.Issuer, entity.Game);
			if (oldEntity != null)
			{
				db.LatestLotteryDraw.Remove(oldEntity);
			}
			db.LatestLotteryDraw.Add(latestLotteryDraw);
			db.SaveChanges();
			return latestLotteryDraw;
		}

		public List<WinningDetail> Create(List<WinningDetail> details, long drawId)
		{
			var db = this.NewDB();
			details.ForEach(detail =>
			{
				detail.DrawId = drawId;
				db.WinningDetail.Add(detail);
			});
			db.SaveChanges();
			return details;
		}

		public void Update(List<WinningDetail> details, long drawId)
		{
			var db = this.NewDB();
			var oldDetails = this.GetWinningDetails(db, drawId);
			details.ForEach(detail => detail.DrawId = drawId);
			if (details.Count != oldDetails.Count)
			{
				// 数量不一致时，先删除，再创建
				oldDetails.ForEach(p => db.WinningDetail.Remove(p));
				details.ForEach(p => db.WinningDetail.Add(p));
			}
			else
			{
				oldDetails = oldDetails.OrderBy(p => p.Serial).ToList();
				details = details.OrderBy(p => p.Serial).ToList();
				for (int i = 0; i < oldDetails.Count; i++)
				{
					var oldDetail = oldDetails[i];
					var detail = details[i];
					oldDetail.Serial = detail.Serial;
					oldDetail.Award = detail.Award;
					oldDetail.NumberOfWinners = detail.NumberOfWinners;
					oldDetail.MoneyPerWinner = detail.MoneyPerWinner;
				}
			}

			db.SaveChanges();
		}
	}
}
